package com.irdstudio.efp.batch.service.impl.hjwpzxbs;

import com.irdstudio.basic.framework.core.bean.TxtFileLoadBean;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.basic.framework.core.util.TimeUtil;
import com.irdstudio.basic.framework.core.util.TxtFileLoadPlugin;
import com.irdstudio.efp.batch.service.facade.hjwpzxbs.SynZxbsLoanRepayDetailService;
import com.irdstudio.efp.batch.service.impl.hjwp.SynAccRepayPlayDetailVO;
import com.irdstudio.efp.batch.service.impl.hjwp.SynFileDataInterface;
import com.irdstudio.efp.console.common.ConsoleConstant;
import com.irdstudio.efp.nls.common.constant.NlsApplyInfoEnums;
import com.irdstudio.efp.report.service.facade.ZxbsAccLoanService;
import com.irdstudio.efp.report.service.facade.ZxbsLoanRepayDetailService;
import com.irdstudio.efp.report.service.facade.ZxbsLoanRepayPlanService;
import com.irdstudio.efp.report.service.vo.ZxbsAccLoanVO;
import com.irdstudio.efp.report.service.vo.ZxbsLoanRepayDetailVO;
import com.irdstudio.efp.report.service.vo.ZxbsLoanRepayPlanVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.irdstudio.basic.framework.core.util.BeanUtility.beanCopy;


/**
 * 互金晚批同步-还款记录同步
 */
@Service("synZxbsLoanRepayDetailService")
public class SynZxbsLoanRepayDetailServiceImpl implements SynZxbsLoanRepayDetailService, SynFileDataInterface {
    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(SynZxbsLoanRepayDetailServiceImpl.class);

    private String sedLoanFilePath = "/home/ocmuser/share/infile/psd/syncfile/";

    private String fileNameOfDat = "idl_dm_loan_rcallbk_info_i.$date$.dat";

    private String fileNamOfOk = "idl_dm_loan_rcallbk_info_i.$date$.ok";

    /**
     * 还款明细服务
     */
    @Autowired
    private ZxbsLoanRepayDetailService loanRepayDetailService;

    private String batchSubDate;

    private Date batchRunDate;

    /**
     * 台账服务
     */
    @Autowired
    private ZxbsAccLoanService accLoanService;

    private static final Map<String, String> repayType = new HashMap<>();

    static {
        //01 正常还款
        //02 提前部分还款
        //03 提前结清
        //04 逾期还款
        //06 按期次提前还款
        //07 部分还款（先还欠款如有剩余提前还本）
        //正常还款
        repayType.put("NS", ConsoleConstant.REPAY_TYPE_01);
        //提前部分还本
        repayType.put("ER", ConsoleConstant.REPAY_TYPE_02);
        //部分还款（先还欠款如有剩余提前还本）--10
        repayType.put("PR", ConsoleConstant.REPAY_TYPE_10);
        //按期次提前还款
        repayType.put("PS", ConsoleConstant.REPAY_TYPE_06);
        //结清
        repayType.put("PO", ConsoleConstant.REPAY_TYPE_03);
        //利费减免
        repayType.put("WV", ConsoleConstant.REPAY_TYPE_09);
    }

    @Autowired
    private ZxbsLoanRepayPlanService loanRepayPlanService;

    @Override
    public Boolean synLoanRepayDetail(String sub_date_date) throws Exception {
        //sub_date_date = "2024-02-21";
        logger.info("批次时间：[{}]的互金还款记录同步批次开始运行", sub_date_date);
        batchSubDate = sub_date_date;
        batchRunDate = new Date();
        String fileUrl = sedLoanFilePath + getCurrentBatchFileName(fileNameOfDat, sub_date_date);
        if (!new File(fileUrl).exists()) {
            throw new RuntimeException("还款明细数据文件不存在,文件路径为：" + fileUrl);
        }
        //判断ok文件里面的数量是否为空
        if (getOkFileDataNum(sedLoanFilePath, fileNamOfOk, sub_date_date) < 1) {
            logger.info("批次时间：[{}]的互金还款记录同步批次获取到的ok文件(文件路径：[{}]；文件名：[{}])中的文件数据条数为空，本次批次结束", sub_date_date, sedLoanFilePath, fileNamOfOk);
            return Boolean.TRUE;
        }
        //校验ok文件
        boolean flag = validateOkFile(getFileNum(fileUrl), sedLoanFilePath, fileNamOfOk, sub_date_date);
        if (!flag) {
            logger.info("批次时间：[{}]的互金还款记录同步批次ok文件校验不通过", sub_date_date);
            return Boolean.FALSE;
        }
        TxtFileLoadPlugin txtFileLoadPlugin = new TxtFileLoadPlugin(fileUrl, "\u0002", "UTF-8", 0, 1000);
        List<TxtFileLoadBean> repayPlanList = txtFileLoadPlugin.run(new SynAccRepayPlayDetailVO());
        // 校验文件
        dueData(repayPlanList, sub_date_date);
        if (repayPlanList.size() != 0) {
            while (!repayPlanList.get(repayPlanList.size() - 1).isReadedComplete) {
                txtFileLoadPlugin.setFirstRead(false);
                repayPlanList = txtFileLoadPlugin.run(new SynAccRepayPlayDetailVO());
                if (repayPlanList.size() == 0) {
                    break;
                }
                dueData(repayPlanList, sub_date_date);
            }
        }
        return Boolean.TRUE;
    }


    private void dueData(List<TxtFileLoadBean> list, String sub_date_date) throws Exception {
        logger.info("批次时间：[{}]的互金还款记录同步批次执行dueData函数开始", sub_date_date);
        if (list == null) {
            return;
        }
        if (list.isEmpty()) {
            return;
        }
        //获取互金传送的还款号集合
        List<String> setlSeqs = list.stream().map(e -> ((SynAccRepayPlayDetailVO) e).getRpyNo()).distinct().collect(Collectors.toList());
        //获取互金传送的还款流水对应的借据号集合
        List<String> loanNos = list.stream().map(e -> ((SynAccRepayPlayDetailVO) e).getLoanNo()).distinct().collect(Collectors.toList());

        //根据还款号 查询出本地的还款记录数据
        List<ZxbsLoanRepayDetailVO> loanRepayDetailAs = loanRepayDetailService.queryByRpyNo(setlSeqs);
        if (loanRepayDetailAs == null) {
            loanRepayDetailAs = new ArrayList<>();
        }
        //根据借据号集合 查询对应的借据信息
        List<ZxbsAccLoanVO> accLoanAs = accLoanService.queryByBillNos(loanNos);

        List<ZxbsLoanRepayDetailVO> loanRepayDetailVOS = new ArrayList<>();

        for (TxtFileLoadBean txtFileLoadBean : list) {
            SynAccRepayPlayDetailVO sedSynAccRepayPlayDetailVO = (SynAccRepayPlayDetailVO) txtFileLoadBean;
            ZxbsLoanRepayDetailVO loanRepayDetailVO = getByRpyNo(loanRepayDetailAs, sedSynAccRepayPlayDetailVO);
            if (Objects.isNull(loanRepayDetailVO)) {
                loanRepayDetailVO = new ZxbsLoanRepayDetailVO();
            }
            beanCopy(sedSynAccRepayPlayDetailVO, loanRepayDetailVO);
            //设置期次
            loanRepayDetailVO.setRepayTerm(Integer.parseInt(sedSynAccRepayPlayDetailVO.getRepayTerm()));
            //如果主键为空，那么主键赋值为还款号
            if (StringUtils.isEmpty(loanRepayDetailVO.getSetlSeq())) {
                loanRepayDetailVO.setSetlSeq(sedSynAccRepayPlayDetailVO.getRpyNo());
            }
            //互金：还款方式
            setSetlType(sedSynAccRepayPlayDetailVO, loanRepayDetailVO);

            // 主动还款日期
            if (StringUtils.isEmpty(loanRepayDetailVO.getSetlApplyDt())) {
                loanRepayDetailVO.setSetlApplyDt(sedSynAccRepayPlayDetailVO.getRetDate());
            }
            if (StringUtils.isEmpty(loanRepayDetailVO.getSetlValDt())) {
                loanRepayDetailVO.setSetlValDt(sedSynAccRepayPlayDetailVO.getRetDate());
            }
            // 生效日期
            // loanRepayDetailVO.setSetlValDt(sub_date_date);
            // 还款时总拖欠费用
            loanRepayDetailVO.setAllOdFeeAmt(BigDecimal.ZERO);
            // 归还费用总计
            loanRepayDetailVO.setSetlTotalFee(sedSynAccRepayPlayDetailVO.getSetlTotalFee());
            // 审批状态 赋值02
            loanRepayDetailVO.setWfApprSts(NlsApplyInfoEnums.NlsApplyState.PASS.getKey());
            loanRepayDetailVO.setRpSts("1");
            // 创建用户
            if (StringUtils.isEmpty(loanRepayDetailVO.getSetlCreateUsr())) {
                loanRepayDetailVO.setSetlCreateUsr(BaseConstant.ADMIN);
            }
            // 创建日期 取批次日期
            if (StringUtils.isEmpty(loanRepayDetailVO.getSetlCreateDt())) {
                loanRepayDetailVO.setSetlCreateDt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            // 最新变更用户
            loanRepayDetailVO.setLastChgUsr(BaseConstant.ADMIN);
            // 最新变更时间
            loanRepayDetailVO.setLastChgDt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            loanRepayDetailVOS.add(loanRepayDetailVO);

            String loanNo = loanRepayDetailVO.getLoanNo();
            ZxbsAccLoanVO accLoanVO = accLoanAs.stream().filter(a -> a.getBillNo().equals(loanNo)).findFirst().orElse(null);
            if (!Objects.isNull(accLoanVO)) {
                // 客户名称
                loanRepayDetailVO.setCustName(accLoanVO.getCusName());
                // 证件类型
                loanRepayDetailVO.setIdType(accLoanVO.getCertType());
                // 证件号
                loanRepayDetailVO.setIdNo(accLoanVO.getCertCode());
                // 放款金额
                loanRepayDetailVO.setDnAmt(accLoanVO.getLoanAmount());
            }

        }
        if (loanRepayDetailVOS.size() > 0) {
            int num = loanRepayDetailService.insertOrUpdate(loanRepayDetailVOS);
            logger.info("批次时间：[{}]的互金还款记录同步批次执行dueData函数插入或更新还款记录表完成，变更的数据为：[{}]", sub_date_date, num);
        }
        logger.info("批次时间：[{}]的互金还款记录同步批次执行dueData函数结束", sub_date_date);
    }

    private void setSetlType(SynAccRepayPlayDetailVO sedSynAccRepayPlayDetailVO, ZxbsLoanRepayDetailVO loanRepayDetailVO) throws Exception {
        if ("NS".equals(sedSynAccRepayPlayDetailVO.getSetlTyp()) || "PR".equals(sedSynAccRepayPlayDetailVO.getSetlTyp()) || "PO".equals(sedSynAccRepayPlayDetailVO.getSetlTyp())) {
            //判断还款日期
            ZxbsLoanRepayPlanVO param = new ZxbsLoanRepayPlanVO();
            param.setTerm(Integer.valueOf(sedSynAccRepayPlayDetailVO.getRepayTerm()));
            param.setRefNbr(sedSynAccRepayPlayDetailVO.getLoanNo());
            ZxbsLoanRepayPlanVO loanRepayPlanByRefNbrAndTerm = loanRepayPlanService.queryByPk(param);
            if (loanRepayPlanByRefNbrAndTerm != null) {
                String endDate = StringUtil.isNullorBank(loanRepayPlanByRefNbrAndTerm.getGraceDate())?loanRepayPlanByRefNbrAndTerm.getStmtDate():loanRepayPlanByRefNbrAndTerm.getGraceDate();
                //判断结束日期和回收日期
                if (TimeUtil.compareDates(endDate,sedSynAccRepayPlayDetailVO.getRetDate())==-1) {
                    //逾期还款
                    loanRepayDetailVO.setSetlTyp(ConsoleConstant.REPAY_TYPE_04);
                    return;
                }
                if (TimeUtil.compareDates(endDate,sedSynAccRepayPlayDetailVO.getRetDate())==0){
                    //逾期还款
                    loanRepayDetailVO.setSetlTyp(ConsoleConstant.REPAY_TYPE_01);
                    return;
                }

            }else{
                if ("0".equals(sedSynAccRepayPlayDetailVO.getRepayTerm()) && "PR".equals(sedSynAccRepayPlayDetailVO.getSetlTyp())){
                    loanRepayDetailVO.setSetlTyp(ConsoleConstant.REPAY_TYPE_02);
                    return;
                }
            }
        }
        loanRepayDetailVO.setSetlTyp(repayType.get(loanRepayDetailVO.getSetlTyp()));
    }
    
    private ZxbsLoanRepayDetailVO getByRpyNo(List<ZxbsLoanRepayDetailVO> list, SynAccRepayPlayDetailVO sedSynAccRepayPlayDetailVO) {
        if (list == null) {
            return null;
        }
        if (list.isEmpty()) {
            return null;
        }
        for (ZxbsLoanRepayDetailVO loanRepayDetailVO : list) {
            if (loanRepayDetailVO.getRpyNo().equals(sedSynAccRepayPlayDetailVO.getRpyNo())
                    && loanRepayDetailVO.getLoanNo().equals(sedSynAccRepayPlayDetailVO.getLoanNo())
                    && loanRepayDetailVO.getSetlApplyDt().equals(sedSynAccRepayPlayDetailVO.getRetDate())
                    && loanRepayDetailVO.getRepayTerm().intValue()==Integer.parseInt(sedSynAccRepayPlayDetailVO.getRepayTerm())
            ) {
                return loanRepayDetailVO;
            }
        }
        return null;
    }

}
